﻿using UnityEngine;
using System.Collections.Generic;
using System;
namespace TTUnityPlugin {
[DisallowMultipleComponent]
public class SingletonMgr : MonoBehaviour {
    private static SingletonMgr container = null;
    private Dictionary<string, object> singletonMap = new Dictionary<string, object>();

    void Awake() {
        DontDestroyOnLoad(gameObject);
    }

    /// <summary>
    ///
    /// </summary>
    /// <returns></returns>
    private static void CheckInstance() {
        if(container == null) {
            container = new GameObject("GameSingletonMgr").AddComponent<SingletonMgr>();
        }
    }

    /// <summary>
    /// 内部调用 应该只有初始化的时候会用到
    /// </summary>
    /// <param name="type"></param>
    private MonoBehaviour AddInitGetInstPrivate(Type type) {
        if(!singletonMap.ContainsKey(type.Name)) {
            singletonMap.Add(type.Name, gameObject.AddComponent(type));
        }
        return singletonMap[type.Name] as MonoBehaviour;
    }

    private T AddGetInstPrivate<T>() where T : MonoBehaviour {
        if(!singletonMap.ContainsKey(typeof(T).Name)) {
            singletonMap.Add(typeof(T).Name, gameObject.AddComponent(typeof(T)));
        }
        return (T)singletonMap[typeof(T).Name];
    }

    private void RemoveInstPrivate<T>() where T : MonoBehaviour {
        if(container != null && singletonMap.ContainsKey(typeof(T).Name)) {
            Destroy((UnityEngine.Object)(singletonMap[typeof(T).Name]));
            singletonMap.Remove(typeof(T).Name);
        }
    }

    private bool HadInstPrivate<T>() where T : MonoBehaviour {
        if(container == null) {
            return false;
        }
        if(singletonMap != null && singletonMap.ContainsKey(typeof(T).Name)) {
            return true;
        }
        return false;
    }

    public static T GetInst<T>() where T : MonoBehaviour {
        CheckInstance();
        return container.AddGetInstPrivate<T>();
    }

    public static void RemoveInst<T>() where T : MonoBehaviour {
        CheckInstance();
        container.RemoveInstPrivate<T>();
    }

    public static bool HadInst<T>() where T : MonoBehaviour {
        CheckInstance();
        return container.HadInstPrivate<T>();
    }
}
}